import json
import re

from django.contrib.auth import logout
from django.contrib.auth.mixins import LoginRequiredMixin
from django import http
from django.shortcuts import render, redirect
from django.urls import reverse
from django.views import View
from apps.areas.models import Area
from apps.users.models import Address
from utils.response_code import RETCODE
from django.core.cache import cache

import logging

logger = logging.getLogger('django')


class AreasView(View):
    def get(self, request):

        area_id = request.GET.get('area_id')

        if not area_id:

            province_list = cache.get('province_list')

            if not province_list:

                try:
                    province_model_list = Area.objects.filter(parent__isnull=True)
                    province_list = []

                    for province_model in province_model_list:
                        province_list.append({'id': province_model.id, 'name': province_model.name})
                except:
                    return http.JsonResponse({'code': RETCODE.NODATAERR, 'errmsg': '数据错误', })

                cache.set('province_list', province_list, 3600)
            return http.JsonResponse({'code': RETCODE.OK, 'errmsg': 'ok', 'province_list': province_list})
        else:
            sub_data = cache.get('sub_area_' + area_id)

            if not sub_data:
                try:
                    parent_model = Area.objects.get(id=area_id)

                    sub_model_list = parent_model.subs.all()

                    sub_list = []

                    for sub_model in sub_model_list:
                        sub_list.append({'id': sub_model.id, 'name': sub_model.name})

                    sub_data = {
                        'id': parent_model.id,
                        'name': parent_model.name,
                        'subs': sub_list
                    }
                except:
                    return http.JsonResponse({'code': RETCODE.NODATAERR, 'errmsg': '数据错误'})

                cache.set('sub_area_' + area_id, sub_data, 3600)
            return http.JsonResponse({'code': RETCODE.OK, 'errmsg': 'ok', 'sub_data': sub_data})


class CreateAddressView(LoginRequiredMixin, View):
    # 创建用户地址
    def post(self, request):
        # 判断地址数量
        count = request.user.addresses.count()
        if count >= 20:
            return http.JsonResponse({'code': RETCODE.PARAMERR, 'errmsg': '地址过多'})
        # 接收数据
        dict = json.loads(request.body.decode())
        receiver = dict.get('receiver')
        province_id = dict.get('province_id')
        city_id = dict.get('city_id')
        district_id = dict.get('district_id')
        place = dict.get('place')
        mobile = dict.get('mobile')
        tel = dict.get('tel')
        email = dict.get('email')
        # 校验数据
        if not all([receiver, province_id, city_id, district_id, place, mobile]):
            return http.JsonResponse({'code': RETCODE.PARAMERR, 'errmsg': '数据不全'})
        if not re.match(r'^1[3-9]\d{9}$', mobile):
            return http.HttpResponseBadRequest('参数mobile有误')
        if tel:
            if not re.match(r'^(0[0-9]{2,3}-)?([2-9][0-9]{6,7})+(-[0-9]{1,4})?$', tel):
                return http.HttpResponseBadRequest('参数tel有误')
        if email:
            if not re.match(r'^[a-z0-9][\w\.\-]*@[a-z0-9\-]+(\.[a-z]{2,5}){1,2}$', email):
                return http.HttpResponseBadRequest('参数email有误')
        # 保存数据
        try:
            address = Address.objects.create(
                user=request.user,
                title=receiver,
                receiver=receiver,
                province_id=province_id,
                city_id=city_id,
                district_id=district_id,
                place=place,
                mobile=mobile,
                tel=tel,
                email=email
            )

            if not request.user.default_address:
                request.user.default_address = address
                request.user.save()
        except:
            return http.JsonResponse({'code': RETCODE.PARAMERR, 'errmsg': '保存地址错误'})

        address_dict = {
            'id': address.id,
            'title': address.title,
            'receiver': address.receiver,
            'province': address.province.name,
            'city': address.city.name,
            'district': address.district.name,
            'place': address.place,
            'mobile': address.mobile,
            'tel': address.tel,
            'email': address.email
        }

        return http.JsonResponse({'code': RETCODE.OK, 'errmsg': 'ok', 'address': address_dict})


class AddressesView(LoginRequiredMixin, View):
    # 展示用户地址
    def get(self, request):
        # 接受用户数据
        user = request.user
        addresses = Address.objects.filter(user=user, is_deleted=False)
        # 对用户地址数据进行遍历
        address_list = []
        for address in addresses:
            address_dict = {
                "id": address.id,
                "title": address.title,
                "receiver": address.receiver,
                "province": address.province.name,
                "province_id": address.province_id,
                "city": address.city.name,
                "city_id": address.city_id,
                "district": address.district.name,
                "district_id": address.district_id,
                "place": address.place,
                "mobile": address.mobile,
                "tel": address.tel,
                "email": address.email
            }
            address_list.append(address_dict)
        # 发送给前段
        dict = {
            'default_address_id': user.default_address_id,
            'addresses': address_list
        }

        return render(request, 'user_center_site.html', context=dict)



class UpdateAddressView(LoginRequiredMixin, View):
    # 更新地址
    def put(self, request, address_id):
        # 接受参数
        dict = json.loads(request.body.decode())
        receiver = dict.get('receiver')
        province_id = dict.get('province_id')
        city_id = dict.get('city_id')
        district_id = dict.get('district_id')
        place = dict.get('place')
        mobile = dict.get('mobile')
        tel = dict.get('tel')
        email = dict.get('email')
        # 校验数据
        if not all([receiver, province_id, city_id, district_id, place, mobile]):
            return http.JsonResponse({'code': RETCODE.PARAMERR, 'errmsg': '数据不全'})
        if not re.match(r'^1[3-9]\d{9}$', mobile):
            return http.HttpResponseBadRequest('参数mobile有误')
        if tel:
            if not re.match(r'^(0[0-9]{2,3}-)?([2-9][0-9]{6,7})+(-[0-9]{1,4})?$', tel):
                return http.HttpResponseBadRequest('参数tel有误')
        if email:
            if not re.match(r'^[a-z0-9][\w\.\-]*@[a-z0-9\-]+(\.[a-z]{2,5}){1,2}$', email):
                return http.HttpResponseBadRequest('参数email有误')
        # 保存数据
        try:
            Address.objects.filter(id=address_id).update(
                user=request.user,
                title=receiver,
                receiver=receiver,
                province_id=province_id,
                city_id=city_id,
                district_id=district_id,
                place=place,
                mobile=mobile,
                tel=tel,
                email=email
            )
        except:
            return http.JsonResponse({'code': RETCODE.PARAMERR, 'errmsg': '数据错误'})

        address = Address.objects.get(id=address_id)
        address_dict = {
            'id': address.id,
            'title': address.title,
            'receiver': address.receiver,
            'province': address.province.name,
            'city': address.city.name,
            'district': address.district.name,
            'place': address.place,
            'mobile': address.mobile,
            'tel': address.tel,
            'email': address.email
        }

        return http.JsonResponse({'code': RETCODE.OK, 'errmsg': 'ok', 'address': address_dict})

    def delete(self, request, address_id):

        try:
            address = Address.objects.get(id=address_id)

            address.is_deleted = True
            address.save()
        except:
            return http.JsonResponse({'code': RETCODE.PARAMERR, 'errmsg': '数据错误'})
        return http.JsonResponse({'code': RETCODE.OK, 'errmsg': 'ok'})


class DefaultAddressView(LoginRequiredMixin, View):
    # 修改默认地址
    def put(self, request, address_id):
        try:
            address = Address.objects.get(id=address_id)
            request.user.default_address = address
            request.user.save()
        except:
            return http.JsonResponse({'code': RETCODE.PARAMERR, 'errmsg': '数据错误'})
        return http.JsonResponse({'code': RETCODE.OK, 'errmsg': 'ok'})


class UpdateTitleAddressView(LoginRequiredMixin, View):
    # 修改标题title
    def put(self, request, address_id):
        # 接收参数
        json_dict = json.loads(request.body.decode())
        title = json_dict.get('title')
        try:
            # 查询地址
            address = Address.objects.get(id=address_id)

            # 设置新的地址标题
            address.title = title
            address.save()
        except:
            return http.JsonResponse({'code': RETCODE.PARAMERR, 'errmsg': '设置地址标题失败'})

        # 4.响应删除地址结果
        return http.JsonResponse({'code': RETCODE.OK, 'errmsg': '设置地址标题成功'})

class ChangePWDView(View):

    def get(self, request):
        return render(request, 'user_center_pass.html')

    def post(self, request):

        o_PWD = request.POST.get('old_password')
        n_PWD = request.POST.get('new_password')
        n_PWD2 = request.POST.get('new_password2')

        if not all([o_PWD, n_PWD, n_PWD2]):
            return http.HttpResponseBadRequest('缺少必要数据')
        if not re.match(r'^[0-9A-Za-z]{8,20}$', n_PWD):
            return http.HttpResponseBadRequest('密码最少8位，最长20位')
        if n_PWD != n_PWD2:
            return http.HttpResponseBadRequest('两次输入的密码不一致')

        user= request.user
        if not user.check_password(o_PWD):
            return http.JsonResponse({'code':RETCODE.PWDERR, 'errmsg':'密码错误'})

        try:
            user.set_password(n_PWD)
            user.save()
        except:
            return http.JsonResponse({'code':RETCODE.PWDERR, 'errmsg':'密码错误'})

        logout(request)
        response = redirect(reverse('users:login'))

        response.delete_cookie('username')
        return response
